﻿using CWCS.Common;
using CWCS.Core.Library.PLCManager;
using CWCS.Entity;
using CWCS.Entity.Convery;
using CWCS.Entity.SRM;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using Nti56.Modbus.Communication.Models;
using Nti56.Modbus.Communication.Services;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;

namespace CWCS.Core.Library.ModbusManager
{
    /// <summary>
    /// 输送机PLC
    /// </summary>
    public class ConveryModbus : PLCHelper
    {
        public static List<ConveryEntity> StationsInfo = new List<ConveryEntity>();
        public List<ConveryGroupEntity> lstRead = new List<ConveryGroupEntity>();
        public static bool IsInit = false;
        private string local_ip;
        private readonly object objLoc = new object();
        public Dictionary<string, bool> PLCConnectStatus = new Dictionary<string, bool>();
        private Dictionary<string, TimerManager> pftDic = new Dictionary<string, TimerManager>();
        private delegate void ReadOPCInfos(object info,int belong);
        private event ReadOPCInfos ReadEquipOPCInfo;
        private delegate void ReConnetPLC(string ip, int retryCount);
        private event ReConnetPLC STAReConnectPLC;
        public int _ReadDBMaxLength = 600;
        ModbusReadWriteService readService = new ModbusReadWriteService();
        ModbusReadWriteService writeService = new ModbusReadWriteService();
        static int[] WriteThreadLocked = new int[3] { 0, 0, 0 };
        public static Dictionary<string, ModbusTcpClient> modbusScanClients = new Dictionary<string, ModbusTcpClient>();
        public static Dictionary<string, ModbusTcpClient> modbusReadClients = new Dictionary<string, ModbusTcpClient>();
        public static Dictionary<string, ModbusTcpClient> modbusWriteClients = new Dictionary<string, ModbusTcpClient>();

        public string FaceCode = ConfigurationManager.AppSettings["FaceCode"].ToString().Trim();
        public string TrayMode = ConfigurationManager.AppSettings["TrayMode"].ToString().Trim();
        public static Dictionary<string, DateTime> OverTime = new Dictionary<string, DateTime>();
        

        public void InitData(List<ConveryEntity> lst, ref string error)
        {
            try
            {
                foreach (var item in lst as List<ConveryEntity>)
                {
                    local_ip = item.Key_ip;
                    if (!ModbusList.ContainsKey(local_ip))
                    {
                        ModbusConnectionInfo connectionInfo = new ModbusConnectionInfo()
                        {
                            Ip = IPAddress.Parse(local_ip),
                            Port = 502,
                            Station = 1
                        };
                        ModbusList.Add(local_ip, connectionInfo);
                        PLCConnectStatus.Add(local_ip, false);

                        var Readconnect = ModbusConnection.Connection(connectionInfo,"R"+ local_ip);
                        var Writeconnect = ModbusConnection.Connection(connectionInfo, "W" + local_ip);
                        var Scanconnect = ModbusConnection.Connection(connectionInfo, "Scan" + local_ip);
                        modbusReadClients[local_ip] = Readconnect.Value;
                        modbusWriteClients[local_ip] = Writeconnect.Value;
                        modbusScanClients[local_ip] = Scanconnect.Value;

                        if (Readconnect.Value.Client.Connected && Writeconnect.Value.Client.Connected)
                        {
                            if (!PLCConnectStatus.ContainsKey(item.Key_ip))
                            {
                                PLCConnectStatus.Add(item.Key_ip, true);
                            }
                            //#region 给输送机PLC写入当前系统生产的托盘类型及拉线所属的面
                            //byte[] byt1 = System.Text.ASCIIEncoding.ASCII.GetBytes(TrayMode.PadRight(10, '\0'));
                            //WritePlc(siemens, 55, 0, byt1);
                            //byte[] byt2 = System.Text.ASCIIEncoding.ASCII.GetBytes(FaceCode);
                            //WritePlc(siemens, 55, 10, byt2);
                            //#endregion
                        }
                        else
                        {
                            if (!PLCConnectStatus.ContainsKey(item.Key_ip))
                            {
                                PLCConnectStatus.Add(item.Key_ip, false);
                            }
                        }
                    }
                    if (!pftDic.ContainsKey(item.Belong))
                    {
                        pftDic.Add(item.Belong, new TimerManager());
                    }
                    ConveryInit(item, local_ip);
                }
                ShowMsg("Init", "输送机初始化化完成");
                IsInit = true;
            }
            catch (Exception ex)
            {
                error = ex.Message;
            }
        }

        public ConveryModbus()
        {
            ReadEquipOPCInfo += new ReadOPCInfos(BatchReadConveryInfo);
            this.STAReConnectPLC += new ReConnetPLC(ReConnect);
        }
        /// <summary>
        /// 初始化输送机
        /// </summary>
        /// <param name="si"></param>
        private void ConveryInit(ConveryEntity si, string strlocal_ip)
        {

            if (si.StationNo == "4001")
            {

            }
            if (si.config == "Convery")
            {
                if (lstRead.Exists(it => it.key_ip.ToString().Trim() == si.Key_ip && it.DBAddress == si.DBAddress && it.Belong == si.Belong))
                {
                    ConveryGroupEntity cr = lstRead.Find(it => it.key_ip.ToString().Trim() == strlocal_ip && it.DBAddress == si.DBAddress && it.Belong == si.Belong.Trim());
                    if (cr != null)
                    {
                        int length = si.value - cr.currentValue;
                        cr.length = si.length * ((si.value - cr.startDB) / si.length) + si.length;
                        cr.currentStatioNo = int.Parse(si.StationNo);
                        cr.currentValue = si.value;
                        cr.lststation.Add(si);
                    }
                }
                else
                {
                    ConveryGroupEntity cr = new ConveryGroupEntity();
                    cr.value = si.value;
                    cr.length = si.length;
                    cr.key_ip = si.Key_ip;
                    cr.DBAddress = si.DBAddress;
                    cr.lststation.Add(si);
                    cr.currentStatioNo = int.Parse(si.StationNo);
                    cr.Belong = si.Belong;
                    cr.startDB = si.value;
                    cr.datatype = si.datatype;
                    cr.scanvalue = si.Scanvalue;
                    lstRead.Add(cr);
                }
                if (!StationsInfo.Exists(it => it.StationNo == si.StationNo && it.Key_ip.ToString().Trim() == si.Key_ip && it.DBAddress == it.DBAddress))
                    StationsInfo.Add(si);
            }

        }

        public void Run(object i_Index)
        {
            Thread threadCom = new Thread(new ParameterizedThreadStart(TimeScan));
            threadCom.IsBackground = true;
            threadCom.Start(i_Index);
        }

        private void TimeScan(object belong)
        {
            while (true)
            {
                TimerManager pfttemp;
                try
                {
                    if (!pftDic.ContainsKey(belong.ToString()))
                    {
                        pfttemp = new TimerManager();
                    }
                    else
                    {
                        pfttemp = pftDic[belong.ToString()];
                    }
                    pfttemp.Start();
                    var lst = lstRead.Where(it => it.Belong == belong.ToString()).ToList();
                    if (lst.Count > 0)
                    {
                        foreach (ConveryGroupEntity csi in lst)
                        {
                            BatchReadConveryInfo(csi, int.Parse(belong.ToString()));
                        }
                    }
                    pfttemp.Stop();
                    var uconnectPLC = PLCConnectStatus.ToArray().Where(x => x.Value == false).ToList();
                    if (uconnectPLC.Count > 0)
                    {
                        ShowEquipmentPLCStatus(new PLCStatus() { _connectStatus = uconnectPLC.FirstOrDefault().Value, _elapsedMilliseconds = pfttemp.Duration, _IP = uconnectPLC.FirstOrDefault().Key });
                    }
                    else
                    {
                        for (int i = 0; i < PLCConnectStatus.Keys.Count; i++)
                        {
                            var key = PLCConnectStatus.ToArray()[i];
                            {
                                ShowEquipmentPLCStatus(new PLCStatus() { _connectStatus = key.Value, _elapsedMilliseconds = pfttemp.Duration, _IP = key.Key });
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    //throw ex;
                }
                Thread.Sleep(500);
            }
        }

        /// <summary>
        /// 读取所属线程所有站台信息
        /// </summary>
        /// <param name="stationinfo"></param>
        private void BatchReadConveryInfo(object obj, int belong)
        {
            if (ReadEquipOPCInfo != null)
            {
                ConveryGroupEntity stat = (ConveryGroupEntity)obj;
                Byte[] ConveryBuffer = new byte[stat.length * 2];

                if (modbusReadClients[stat.key_ip].Client.Connected && modbusWriteClients[stat.key_ip].Client.Connected && modbusScanClients[stat.key_ip].Client.Connected)
                {
                    var result = readService.ReadByte(stat.startDB, (ushort)(stat.length * 2), modbusReadClients[stat.key_ip], "R" + belong);
                    if (result.IsSucceed)
                    {
                        result.Value.CopyTo(ConveryBuffer, 0);
                        stat.cFlag = true;
                        BindListStation(ConveryBuffer, stat, stat.startDB, stat.startDB + stat.length * 2);
                    }
                    else
                    {
                        stat.cFlag = false;
                        ReConnect(stat.key_ip, 1);
                    }
                }
                else
                {
                    stat.cFlag = false;
                    ReConnect(stat.key_ip, 1);
                }
                if (!PLCConnectStatus.ContainsKey(stat.key_ip))
                    PLCConnectStatus.Add(stat.key_ip, stat.cFlag);
                else
                    PLCConnectStatus[stat.key_ip] = stat.cFlag;
                if (StationsInfo != null)
                    ShowUI(StationsInfo);
            }
        }

        #region 数据解析
        /// <summary>
        /// 绑定任务信息
        /// </summary>
        /// <param name="stationno"></param>
        /// <param name="byt"></param>
        private void BindStation(string stationno, byte[] byt)
        {
            ConveryEntity si = StationsInfo.Find(
              delegate(ConveryEntity ss)
              {
                  return ss.StationNo == stationno;
              });
            if (si != null)
            {
                if (si.C_TaskInfo.readFlag == "2")
                {
                    si.C_TaskInfo.readFlag = "3";
                    return;
                }
                byte[] byttemp = new byte[byt.Length - 6];
                Array.Copy(byt, 6, byttemp, 0, byttemp.Length);
                byttemp = byttemp.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                Array.Copy(byttemp, 0, byt, 6, byttemp.Length);

                si.C_TaskInfo.tasknum = byt[0] * 256 + byt[1];//任务信息
                si.C_TaskInfo.fromstation = byt[2] * 256 + byt[3];//起始站台
                si.C_TaskInfo.tostation = byt[4] * 256 + byt[5];//目标站台
                si.C_TaskInfo.gooodstype = byt[6];//货物类型
                si.C_TaskInfo.checkinfo = byt[7];//设备空闲状态 1是空闲，2是有货
                si.C_TaskInfo.faultflag = byt[8];//总故障指令
                si.C_TaskInfo.field1 = byt[11];//备用1
                si.C_TaskInfo.field2 = byt[12];
                si.C_TaskInfo.readFlag = "1";
                byte[] sbarcode = new byte[16];
                Array.Copy(byt, 14, sbarcode, 0, 16);





                si.C_TaskInfo.barcode = System.Text.ASCIIEncoding.ASCII.GetString(sbarcode).Replace(" ", "").TrimEnd('\0').Trim('\r');//下层条码

                if (si.C_TaskInfo.tasknum == 0 && si.C_TaskInfo.tostation == 0)
                {
                    si.C_TaskInfo.moveFlag = false;
                }
                if ((si.C_TaskInfo.tasknum == 0 && si.C_TaskInfo.tostation == 0) || si.C_TaskInfo.tostation == 1)
                {
                    si.C_TaskInfo.applyFlag = false;
                }
                if (si.C_TaskInfo.faultflag == 100)
                {
                    #region 添加堆垛机长时间未取货报警
                    if (si.C_TaskInfo.tasknum >= 1000 && si.StationType == 5)
                    {
                        if (!si.C_TaskInfo.moveFlag)
                        {
                            si.C_TaskInfo.moveFlag = true;
                            si.C_TaskInfo.moveTime = DateTime.Now;
                        }
                        else
                        {
                            if ((DateTime.Now - si.C_TaskInfo.moveTime).TotalMinutes > 10)
                            {
                                si.C_TaskInfo.faultflag = 998;
                            }
                        }
                    }

                    #endregion
                    #region 添加WCS长时间未给目标地址报警
                    if (si.C_TaskInfo.stationno == si.C_TaskInfo.tostation.ToString() && si.C_TaskInfo.tasknum >= 1000 && si.StationType == 4)
                    {
                        if (!si.C_TaskInfo.applyFlag)
                        {
                            si.C_TaskInfo.applyFlag = true;
                            si.C_TaskInfo.applyTime = DateTime.Now;
                        }
                        else
                        {
                            if ((DateTime.Now - si.C_TaskInfo.applyTime).TotalMinutes > 10)
                            {
                                si.C_TaskInfo.faultflag = 999;
                            }
                        }
                    }
                    #endregion
                }
                if (si.C_TaskInfo.mode == "3") //工装扫码
                {
                    if (si.C_TaskInfo.faultflag == 0)
                        si.C_TaskInfo.faultflag = 100;
                }
                if (si.C_TaskInfo.tostation == 8888)  
                {
                    si.C_TaskInfo.faultflag = 997;
                }
                #region 扫码站台
                if (si.C_TaskInfo.datatype == "SCAN" && si.C_TaskInfo.tasknum == 0)
                {
                    si.C_TaskInfo.scanbarcode = "";
                    si.C_TaskInfo.scanitemcode1 = "";
                    si.C_TaskInfo.scanitemcode2 = "";
                }
                if (si.C_TaskInfo.datatype == "SCAN" && si.C_TaskInfo.stationno == si.C_TaskInfo.tostation.ToString())
                {
                    if (si.C_TaskInfo.mode == "1")
                    {
                        Byte[] ConveryBuffer = new byte[si.Scanlength * 2];
                        var result = readService.ReadByte(si.Scanvalue, (ushort)(si.Scanlength * 2), modbusReadClients[si.Key_ip], "Rbarcode" + si.Key_ip);
                        if (result.IsSucceed)
                        {
                            result.Value.CopyTo(ConveryBuffer, 0);
                            byte[] scanbarcode = new byte[si.Scanlength * 2];
                            Array.Copy(ConveryBuffer, 0, scanbarcode, 0, si.Scanlength * 2);
                            scanbarcode = scanbarcode.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                            si.C_TaskInfo.scanbarcode = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(scanbarcode));//条码
                        }
                    }
                    else if (si.C_TaskInfo.mode == "2")
                    {
                        Byte[] ConveryBuffer = new byte[si.ItemCodeScanlength * 2];
                        var result = readService.ReadByte(si.ItemCodeScanvalue, (ushort)(si.ItemCodeScanlength * 2), modbusReadClients[si.Key_ip], "Ritemcode" + si.Key_ip);
                        if (result.IsSucceed)
                        {
                            result.Value.CopyTo(ConveryBuffer, 0);
                            byte[] sbarcode1 = new byte[si.ItemCodeScanlength];
                            byte[] sbarcode2 = new byte[si.ItemCodeScanlength];
                            Array.Copy(ConveryBuffer, 0, sbarcode1, 0, si.ItemCodeScanlength);
                            sbarcode1 = sbarcode1.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                            si.C_TaskInfo.scanitemcode1 = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1));//条码1
                            Array.Copy(ConveryBuffer, si.ItemCodeScanlength, sbarcode2, 0, si.ItemCodeScanlength);
                            sbarcode2 = sbarcode2.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                            si.C_TaskInfo.scanitemcode2 = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode2));//条码2
                        }
                    }
                }
                #endregion

                if (si.C_TaskInfo.stationno == si.C_TaskInfo.tostation.ToString() || si.C_TaskInfo.stationno == "1905"|| si.C_TaskInfo.stationno == "1764" || si.C_TaskInfo.stationno == "2135" || si.C_TaskInfo.stationno == "1416")
                {
                    ShowEquipmentTaskInfo(si.C_TaskInfo);//业务处理
                }
            }
        }

        /// <summary>
        /// 解析数据
        /// </summary>
        /// <param name="byt"></param>
        /// <param name="cr"></param>
        private void BindListStation(byte[] byt, ConveryGroupEntity cr, int startValue, int endValue)
        {
            //lock (obj)
            {
                int i_Length = cr.length;
                foreach (var item in cr.lststation.Where(it => it.value >= startValue && it.value < endValue).OrderBy(it => it.StationNo))
                {
                    ConveryEntity convery = item as ConveryEntity;
                    ConveryEntity si = StationsInfo.Find(
                          delegate(ConveryEntity ss)
                          {
                              return ss.StationNo == convery.StationNo;
                          }
                     );
                    if (si != null)
                    {
                        byte[] bytetemp = new byte[si.length*2];

                        Array.Copy(byt, (si.value - startValue)*2, bytetemp, 0, si.length*2);
                        if (bytetemp != null)
                        {
                            //可采用异步方式
                            BindStation(si.StationNo, bytetemp);//绑定信息
                        }
                    }
                    i_Length = i_Length - si.length;
                }
            }

        }

        #endregion

        /// <summary>
        /// 重新连接
        /// </summary>
        /// <param name="strIP"></param>
        /// <param name="retryCount"></param>
        private void ReConnect(string strIP, int retryCount = 1)
        {
            try
            {
                if (STAReConnectPLC != null)
                {
                    lock (objLoc)
                    {
                        ShowMsg("Break", string.Format("PLC:{0},连接断开,系统开始自动重连...", strIP));
                        if (ModbusList.ContainsKey(strIP))
                        {
                            bool flag = true;
                            int i_Count = 1;
                            while (flag)
                            {
                                if (i_Count > retryCount)
                                    break;
                                //断开连接
                                modbusReadClients[strIP].Client?.Close();
                                modbusWriteClients[strIP].Client?.Close();
                                modbusScanClients[strIP].Client?.Close();
                                ShowMsg("Break", string.Format("PLC：{0}，尝试连接次数：{1}", strIP, i_Count));
                                var Readconnect = ModbusConnection.Connection(ModbusList[strIP], "R" + strIP);
                                var Writeconnect = ModbusConnection.Connection(ModbusList[strIP], "W" + strIP);
                                var Scanconnect = ModbusConnection.Connection(ModbusList[strIP], "Scan" + strIP);

                                modbusReadClients[strIP] = Readconnect.Value;
                                modbusWriteClients[strIP] = Writeconnect.Value;
                                modbusScanClients[strIP] = Scanconnect.Value;

                                if (Readconnect.Value.Client.Connected && Writeconnect.Value.Client.Connected)
                                {
                                    //#region 给输送机PLC写入当前系统生产的托盘类型及生产线面
                                    //byte[] byt1 = System.Text.ASCIIEncoding.ASCII.GetBytes(TrayMode.PadRight(10, '\0'));
                                    //WritePlc(ModbusList[strIP], 55, 0, byt1);
                                    //byte[] byt2 = System.Text.ASCIIEncoding.ASCII.GetBytes(FaceCode);
                                    //WritePlc(ModbusList[strIP], 55, 10, byt2);
                                    //#endregion

                                    ShowMsg("Break", string.Format("PLC：{0}，连接成功", strIP, i_Count));
                                    flag = false;
                                    break;
                                }
                                else
                                {
                                    i_Count++;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                ShowMsg("Break", string.Format("PLC：{0},重新链接失败！", strIP));
            }
        }
        /// <summary>
        /// 清理电池信息或者托盘条码尾巴
        /// </summary>
        /// <param name="barcode"></param>
        private string clearbarcodeInfo(string barcode)
        {

            char[] c = new char[5];
            c[0] = '\0';
            c[1] = '\r';
            c[2] = '\n';
            c[3] = ' ';
            c[4] = ' ';
            barcode = barcode.Replace(c[0], c[4]).Replace("\r", "").Replace("\n", "").Replace(" ", "").Replace("", "").Trim();
            return barcode;
        }
        public string[] ReadBarcodeplcInfo(string stationno, string zonecode, string mode)
        {
            string[] scanbarcode = new string[] { };
            if (zonecode == "HC")
            {
                byte[] ConveryBuffer = new byte[420];
                lock (this)
                {
                    var result = readService.ReadByte(0, 420, modbusReadClients["172.72.73.60"],"R1");
                    if (result.IsSucceed)
                    {
                        result.Value.CopyTo(ConveryBuffer, 0);
                        if (mode == "1")
                        {
                            scanbarcode = new string[1];
                            switch (stationno)
                            {
                                case "1001":
                                    byte[] sbarcode1001 = new byte[12];
                                    Array.Copy(ConveryBuffer, 0, sbarcode1001, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1001));
                                    break;
                                case "1014":
                                    byte[] sbarcode1014 = new byte[12];
                                    Array.Copy(ConveryBuffer, 12, sbarcode1014, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1014));
                                    break;
                                case "1037":
                                    byte[] sbarcode1037 = new byte[12];
                                    Array.Copy(ConveryBuffer, 24, sbarcode1037, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1037));
                                    break;
                                case "1046":
                                    byte[] sbarcode1046 = new byte[12];
                                    Array.Copy(ConveryBuffer, 36, sbarcode1046, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1046));
                                    break;
                                case "1216":
                                    byte[] sbarcode1216 = new byte[12];
                                    Array.Copy(ConveryBuffer, 48, sbarcode1216, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1216));
                                    break;
                                case "1219":
                                    byte[] sbarcode1219 = new byte[12];
                                    Array.Copy(ConveryBuffer, 60, sbarcode1219, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1219));
                                    break;
                                case "1224":
                                    byte[] sbarcode1224 = new byte[12];
                                    Array.Copy(ConveryBuffer, 72, sbarcode1224, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1224));
                                    break;
                                case "1230":
                                    byte[] sbarcode1230 = new byte[12];
                                    Array.Copy(ConveryBuffer, 84, sbarcode1230, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1230));
                                    break;
                                case "1013":
                                    byte[] sbarcode1013 = new byte[12];
                                    Array.Copy(ConveryBuffer, 96, sbarcode1013, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1013));
                                    break;
                                case "1036":
                                    byte[] sbarcode1036 = new byte[12];
                                    Array.Copy(ConveryBuffer, 108, sbarcode1036, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1036));
                                    break;
                                case "1050":
                                    byte[] sbarcode1050 = new byte[12];
                                    Array.Copy(ConveryBuffer, 120, sbarcode1050, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1050));
                                    break;
                                case "1056":
                                    byte[] sbarcode1056 = new byte[12];
                                    Array.Copy(ConveryBuffer, 132, sbarcode1056, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1056));
                                    break;
                            }
                        }
                        else if (mode == "2")
                        {
                            scanbarcode = new string[2];
                            switch (stationno)
                            {
                                case "1008":
                                    byte[] sitemcode11008 = new byte[30];
                                    byte[] sitemcode21008 = new byte[30];
                                    Array.Copy(ConveryBuffer, 240, sitemcode11008, 0, 30);
                                    Array.Copy(ConveryBuffer, 270, sitemcode21008, 0, 30);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode11008));
                                    scanbarcode[1] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode21008));
                                    break;
                                case "1031":
                                    byte[] sitemcode11031 = new byte[30];
                                    byte[] sitemcode21031 = new byte[30];
                                    Array.Copy(ConveryBuffer, 300, sitemcode11031, 0, 30);
                                    Array.Copy(ConveryBuffer, 330, sitemcode21031, 0, 30);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode11031));
                                    scanbarcode[1] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode21031));
                                    break;
                                case "1247":
                                    byte[] sitemcode11247 = new byte[30];
                                    byte[] sitemcode21247 = new byte[30];
                                    Array.Copy(ConveryBuffer, 360, sitemcode11247, 0, 30);
                                    Array.Copy(ConveryBuffer, 390, sitemcode21247, 0, 30);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode11247));
                                    scanbarcode[1] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode21247));
                                    break;
                            }
                        }
                    }
                }
            }
            if (zonecode == "FR")
            {
                byte[] ConveryBuffer = new byte[480];
                lock (this)
                {
                    var result = readService.ReadByte(0, 480, modbusReadClients["172.72.73.60"], "R1");
                    if (result.IsSucceed)
                    {
                        result.Value.CopyTo(ConveryBuffer, 0);
                        if (mode == "1")
                        {
                            scanbarcode = new string[1];
                            switch (stationno)
                            {
                                case "1070":
                                    byte[] sbarcode1070 = new byte[12];
                                    Array.Copy(ConveryBuffer, 0, sbarcode1070, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1070));
                                    break;
                                case "1263":
                                    byte[] sbarcode1263 = new byte[12];
                                    Array.Copy(ConveryBuffer, 12, sbarcode1263, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1263));
                                    break;
                                case "1308":
                                    byte[] sbarcode1308 = new byte[12];
                                    Array.Copy(ConveryBuffer, 24, sbarcode1308, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1308));
                                    break;
                                case "1318":
                                    byte[] sbarcode1318 = new byte[12];
                                    Array.Copy(ConveryBuffer, 36, sbarcode1318, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1318));
                                    break;
                                case "1103":
                                    byte[] sbarcode1103 = new byte[12];
                                    Array.Copy(ConveryBuffer, 48, sbarcode1103, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1103));
                                    break;
                                case "1117":
                                    byte[] sbarcode1117 = new byte[12];
                                    Array.Copy(ConveryBuffer, 60, sbarcode1117, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1117));
                                    break;
                                case "1130":
                                    byte[] sbarcode1130 = new byte[12];
                                    Array.Copy(ConveryBuffer, 72, sbarcode1130, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1130));
                                    break;
                                case "1344":
                                    byte[] sbarcode1344 = new byte[12];
                                    Array.Copy(ConveryBuffer, 84, sbarcode1344, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1344));
                                    break;
                                case "1157":
                                    byte[] sbarcode1157 = new byte[12];
                                    Array.Copy(ConveryBuffer, 96, sbarcode1157, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1157));
                                    break;
                                case "1253":
                                    byte[] sbarcode1253 = new byte[12];
                                    Array.Copy(ConveryBuffer, 108, sbarcode1253, 0, 12);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1253));
                                    break;
                            }
                        }
                        else if (mode == "2")
                        {
                            scanbarcode = new string[2];
                            switch (stationno)
                            {
                                case "1063":
                                    byte[] sitemcode11063 = new byte[30];
                                    byte[] sitemcode21063 = new byte[30];
                                    Array.Copy(ConveryBuffer, 240, sitemcode11063, 0, 30);
                                    Array.Copy(ConveryBuffer, 270, sitemcode21063, 0, 30);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode11063));
                                    scanbarcode[1] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode21063));
                                    break;
                                case "1072":
                                    byte[] sitemcode11072 = new byte[30];
                                    byte[] sitemcode21072 = new byte[30];
                                    Array.Copy(ConveryBuffer, 300, sitemcode11072, 0, 30);
                                    Array.Copy(ConveryBuffer, 330, sitemcode21072, 0, 30);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode11072));
                                    scanbarcode[1] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode21072));
                                    break;
                                case "1288":
                                    byte[] sitemcode11288 = new byte[30];
                                    byte[] sitemcode21288 = new byte[30];
                                    Array.Copy(ConveryBuffer, 360, sitemcode11288, 0, 30);
                                    Array.Copy(ConveryBuffer, 390, sitemcode21288, 0, 30);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode11288));
                                    scanbarcode[1] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode21288));
                                    break;
                                case "1353":
                                    byte[] sitemcode11353 = new byte[30];
                                    byte[] sitemcode21353 = new byte[30];
                                    Array.Copy(ConveryBuffer, 420, sitemcode11353, 0, 30);
                                    Array.Copy(ConveryBuffer, 450, sitemcode21353, 0, 30);
                                    scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode11353));
                                    scanbarcode[1] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sitemcode21353));
                                    break;
                            }
                        }
                    }
                }
            }
            return scanbarcode;
        }

        public string[] ReadStaInfo(string EquipNum, int index = 0)
        {
            string[] info = new string[12] { "0", "0" , "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"};           
            ConveryEntity si = StationsInfo.Find(
                 delegate (ConveryEntity ss)
                 {                   
                     return ss.StationNo == EquipNum.ToString() && ss.C_TaskInfo.readFlag=="1";
                 }
             );
            if (si != null)
            {
                info[0] = si.C_TaskInfo.stationno.ToString();
                info[1] = si.C_TaskInfo.tasknum.ToString();
                info[2] = si.C_TaskInfo.barcode;
                info[3] = si.C_TaskInfo.gooodstype.ToString();
                info[4] = si.C_TaskInfo.fromstation.ToString();
                info[5] = si.C_TaskInfo.tostation.ToString();
                info[6] = si.C_TaskInfo.checkinfo.ToString();
                info[7] = si.C_TaskInfo.NGType.ToString();
                info[8] = si.C_TaskInfo.faultflag.ToString();
                info[9] = si.C_TaskInfo.wcsError.ToString();
                info[10] = si.C_TaskInfo.field1.ToString();
                info[11] = si.C_TaskInfo.field2.ToString();
            }

            return info;
        }

        public string[] ReadscanplcInfo(string stationno, string mode)
        {
            string[] scanbarcode = new string[2];
            ConveryEntity si = StationsInfo.Find(
                delegate (ConveryEntity ss)
                {
                    return ss.StationNo == stationno;
                }
            );
            if (si != null)
            {
                if (modbusScanClients[si.Key_ip].Client.Connected)
                {
                    if (mode == "1")
                    {
                        Byte[] ConveryBuffer = new byte[si.Scanlength * 2];
                        var result = readService.ReadByte(si.Scanvalue, (ushort)(si.Scanlength * 2), modbusScanClients[si.Key_ip], "Rbarcode" + si.Key_ip);
                        if (result.IsSucceed)
                        {
                            result.Value.CopyTo(ConveryBuffer, 0);
                            byte[] sbarcode = new byte[si.Scanlength * 2];
                            Array.Copy(ConveryBuffer, 0, sbarcode, 0, si.Scanlength * 2);
                            sbarcode = sbarcode.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                            scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode));//条码
                        }
                    }
                    else if (mode == "2")
                    {
                        Byte[] ConveryBuffer = new byte[si.ItemCodeScanlength * 2];
                        var result = readService.ReadByte(si.ItemCodeScanvalue, (ushort)(si.ItemCodeScanlength * 2), modbusScanClients[si.Key_ip], "Ritemcode" + si.Key_ip);
                        if (result.IsSucceed)
                        {
                            result.Value.CopyTo(ConveryBuffer, 0);
                            byte[] sbarcode1 = new byte[si.ItemCodeScanlength];
                            byte[] sbarcode2 = new byte[si.ItemCodeScanlength];
                            Array.Copy(ConveryBuffer, 0, sbarcode1, 0, si.ItemCodeScanlength);
                            sbarcode1 = sbarcode1.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                            scanbarcode[0] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode1));//条码1
                            Array.Copy(ConveryBuffer, si.ItemCodeScanlength, sbarcode2, 0, si.ItemCodeScanlength);
                            sbarcode2 = sbarcode2.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                            scanbarcode[1] = clearbarcodeInfo(System.Text.ASCIIEncoding.ASCII.GetString(sbarcode2));//条码2
                        }
                    }
                }
            }
            return scanbarcode;
        }

        private bool Write(string[] str, string equipmentno)
        {
            ConveryEntity si = StationsInfo.Find(
                 delegate (ConveryEntity ss)
                 {
                     return ss.StationNo == equipmentno;
                 }
             );
            if (si != null)
            {
                byte[] byt = new byte[si.length * 2];
                string strLog = "";
                if (str.Length > 2)
                {
                    for (int i = 1; i < str.Length; i++)
                    {
                        if (i == 2)//下层条码
                        {
                            byte[] byttem = System.Text.ASCIIEncoding.ASCII.GetBytes(str[i].PadRight(16, '\0'));
                            Array.Copy(byttem, 0, byt, 14, 16);
                        }
                        else
                        {
                            if (i == 1)//任务号
                            {
                                if (str[i].Trim() == null || str[i].Trim() == "" || str[i] == "\0\0#\0\0\0\0" || str[i] == "\0\0\0\0\0\0\0\0")//电控这里默认值不是为零 
                                    str[i] = "0";
                                Array.Copy(ConvertHelper.GetHexBytes(str[i]), 0, byt, 0, 2);
                            }
                            else if (i == 3)//货物类型3、
                            {
                                Array.Copy(ConvertHelper.GetBytes(str[i]), 0, byt, 6, 1);
                            }
                            else if (i > 3 && i < 6)//起始地址4、目标地址5
                            {
                                Array.Copy(ConvertHelper.GetHexBytes(str[i]), 0, byt, (i - 3) * 2, 2);
                            }
                        }
                        strLog += str[i] + ",";
                    }
                    byte[] byttemp = new byte[byt.Length - 6];
                    Array.Copy(byt, 6, byttemp, 0, byttemp.Length);
                    byttemp = byttemp.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                    Array.Copy(byttemp, 0, byt, 6, byttemp.Length);
                }
                if (true)//调试模式
                {
                    if (modbusWriteClients[si.Key_ip].Client.Connected)
                    {
                        if (writeService.WriteByte(si.value, byt, modbusWriteClients[si.Key_ip], si.StationNo).IsSucceed)
                        {
                            si.C_TaskInfo.readFlag = "2";
                            return true;
                        }
                    }
                    return false;
                }
            }
            return false;
        }
        private bool Write(string[] str, string equipmentno, int index, int length)
        {
            ConveryEntity si = StationsInfo.Find(
                 delegate (ConveryEntity ss)
                 {
                     return ss.StationNo == equipmentno;
                 }
             );
            if (si != null)
            {
                byte[] byt = new byte[length];
                Array.Copy(ConvertHelper.GetHexBytes(str[1]), 0, byt, 0, length);
                if (modbusWriteClients[si.Key_ip].Client.Connected)
                {
                    if (writeService.WriteByte(si.value + index / 2, byt, modbusWriteClients[si.Key_ip], "W" + si.Belong).IsSucceed)
                    {
                        si.C_TaskInfo.readFlag = "2";
                        return true;
                    }
                }
                return false;
            }
            return false;
        }

        public bool WriteScanInfo(string str, string equipmentno)
        {
            ConveryEntity si = StationsInfo.Find(
                 delegate (ConveryEntity ss)
                 {
                     return ss.StationNo == equipmentno;
                 }
             );
            if (si != null)
            {
                if (si.C_TaskInfo.datatype == "SCAN")
                {
                    byte[] byttem = System.Text.ASCIIEncoding.ASCII.GetBytes(str.PadRight(16, '\0'));
                    byttem = byttem.Select((x, i) => new { x, i }).GroupBy(x => x.i / 2).SelectMany(x => new byte[] { x.Last().x, x.First().x }).ToArray();
                    if (modbusScanClients[si.Key_ip].Client.Connected)
                    {
                        if (writeService.WriteByte(si.Scanvalue, byttem, modbusScanClients[si.Key_ip], "Wbarcode" + si.Key_ip).IsSucceed)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public bool Write(STACommand cmd, string[] str, string equipmentno, int index, int length)
        {
            bool flag = false;
            ConveryEntity si = StationsInfo.Find(
            delegate (ConveryEntity ss)
            {
                return ss.StationNo == equipmentno;
            }
            );
            if (si != null)
            {
                //if (Interlocked.Exchange(ref WriteThreadLocked[int.Parse(si.Belong)-1], 1) == 0)
                //{
                    switch (cmd)
                    {
                        case STACommand.ClearToStation:
                            flag = Write(str, equipmentno, index, length);
                            break;
                        case STACommand.ReWrite:
                            flag = Write(str, equipmentno);
                            break;
                    }
                //    Interlocked.Exchange(ref WriteThreadLocked[int.Parse(si.Belong)-1], 0);
                //}
            }
            return flag;
        }

        public override string[] ReadPLCInfo(string EquipNum, int index = 0)
        {
            throw new NotImplementedException();
        }

        public string[] ReadStationInfoByClent(string station)
        {
            string[] info = new string[14];
            ConveryEntity si = StationsInfo.Find(
            delegate (ConveryEntity ss)
            {
                return ss.StationNo == station;
            }
        );
            if (si != null)
            {
                info[0] = si.C_TaskInfo.stationno.ToString();
                info[1] = si.C_TaskInfo.tasknum.ToString();
                info[2] = si.C_TaskInfo.barcode;
                info[3] = si.C_TaskInfo.datatype == "SCAN" && si.C_TaskInfo.mode == "1" ? si.C_TaskInfo.scanbarcode : si.C_TaskInfo.barcode;
                info[4] = si.C_TaskInfo.gooodstype.ToString();
                info[5] = si.C_TaskInfo.fromstation.ToString();
                info[6] = si.C_TaskInfo.tostation.ToString();
                info[7] = si.C_TaskInfo.checkinfo.ToString();
                info[8] = si.C_TaskInfo.NGType.ToString();
                info[9] = si.C_TaskInfo.faultflag.ToString();
                info[10] = si.C_TaskInfo.wcsError.ToString();
                info[11] = si.C_TaskInfo.field1.ToString();
                info[12] = si.C_TaskInfo.field2.ToString();
                info[13] = si.StationType.ToString();
            }
            return info;
        }
    }
}
